package ASWebDavTest 
{
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.FileReference;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.net.URLRequestMethod;
	import flash.utils.ByteArray;

	public class LocalFile extends BaseFile
	{
		protected var fileSystemInfo:FileReference;
		protected const chunkSize:int = 10000;
		protected var currentPos:int = 0;
		protected var currentSize:int = 0;
		protected var uploadUrl:String;
		
		public function LocalFile(Parent:BaseFile, Url:String, FileInfo:FileReference)
		{
			super(Parent);
			
			this.url = Url;
			this.fileSystemInfo = FileInfo;
		}
		
		protected function get FileSystemInfo():FileReference
		{
			if (fileSystemInfo == null)
				Load(1);
			return fileSystemInfo;
		}
		
		protected function get FileInfo():FileReference
		{
			return FileSystemInfo;
		}
		
		public override function get Url():String
		{
			if (super.Url != null)
				return super.Url;
			return fileSystemInfo.name;
		}
		public override function set Url(value:String):void
		{
			super.Url = value;
			if (fileSystemInfo != null && fileSystemInfo.name != value)
				throw new Error("Not supported!");
		}
		
		public override function get SizeBytes():int
		{
			if (FileInfo == null)
				return 0;
			return FileInfo.size; 
		}
		
		public override function get CreatedUtc():Date 
		{
			return FileSystemInfo.creationDate; 
		}
		
		public override function get ModifiedUtc():Date
		{
			return FileSystemInfo.modificationDate;
		}
		
		public override function get Name():String
		{
			return FileSystemInfo.name;
		}
		
		public override function get IsFolder():Boolean
		{
			return false;
		}
		
		public override function Load(depth:int):void
		{
			if (depth <= 0)
				return;
			/*
			//if (fileSystemInfo == null)
				//fileSystemInfo = new DirectoryInfo(Url);
			if (beenLoaded == false)
			{
				beenLoaded = true;
				try
				{
					foreach (var subFolder in DirInfo.GetDirectories())
						Files.Add(new LocalFile(this, subFolder));
				}
				catch { }
				try
				{
					foreach (var file in DirInfo.GetFiles())
						Files.Add(new LocalFile(this, file));
				}
				catch { }
			}
			
			// Tell tree we have new children
			if(IsFolder)
				base.Load(depth);
			
			// Tell children to load
			foreach (var file in Files)
				file.Load(depth - 1);
			*/
		}
		
		public function Upload(url:String):void
		{
			this.uploadUrl = url;
			this.currentPos = 0;
			UploadNextChunk();
		}
		
		protected function UploadNextChunk():void
		{
			var size:int = Math.min(FileInfo.data.length - currentPos, chunkSize);
			if (size == 0)
			{
				trace("Upload complete!");
				dispatchEvent(new Event("UploadComplete"));
			}
			else
				UploadChunk(uploadUrl, FileInfo.data, currentPos, size);
		}
		
		protected function UploadChunk(Url:String, Data:ByteArray, StartIndex:int, Size:int):void
		{
			// Setup chunk
			currentSize = Size;
			var endIndex:int = StartIndex + Size - 1;
			var rangeText:String = "bytes " + StartIndex + "-" + endIndex + "/" + Data.length;
			trace(rangeText);

			var chunk:ByteArray = new ByteArray();
			Data.position = StartIndex;
			Data.readBytes(chunk, 0, Size);
			trace("Uploading " + rangeText);

			// Setup request
			var request:URLRequest = new URLRequest(Url);
			request.url = Url;
			request.contentType = 'application/octet-stream';
			request.method = "PUT";
			request.requestHeaders.push(new URLRequestHeader("Translate", "f"));
			request.requestHeaders.push(new URLRequestHeader("Content-Range", rangeText));
			request.data = chunk;
			
			// Trap events
			//loader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, OnResponse);
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, OnStatus);
			loader.addEventListener(IOErrorEvent.IO_ERROR, OnError);
			loader.addEventListener(ProgressEvent.PROGRESS, OnProgress);
			loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, OnSecurityError);
			loader.addEventListener(Event.COMPLETE, OnComplete);
			loader.load(request);	
		}
		
		protected function OnResponse(e:Event=null):void
		{
			trace("OnResponse");
			dispatchEvent(e);
		}
		
		protected function OnStatus(e:Event=null):void
		{
			trace("OnStatus");
			dispatchEvent(e);
		}
		
		protected function OnError(e:Event=null):void
		{
			trace("OnError" + e.toString());
			UploadNextChunk();
			e.stopImmediatePropagation();
			e.stopPropagation();
			e.preventDefault();
			//dispatchEvent(e);
		}
		
		protected function OnProgress(e:Event=null):void
		{
			trace("OnProgress");
			dispatchEvent(e);
		}
		
		protected function OnSecurityError(e:Event=null):void
		{
			trace("OnSecurityError");
			dispatchEvent(e);
		}
		
		protected function OnComplete(e:Event=null):void
		{
			trace("OnComplete");
			currentPos += currentSize;
			UploadNextChunk();
			dispatchEvent(e);
		}
		
	}

}